package com.cencat.merchant.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cencat.merchant.entity.Merchant;
import com.cencat.merchant.mapper.MerchantMapper;
import com.cencat.merchant.service.MerchantService;
import com.cencat.merchant.vo.MerchantVO;
import com.cencat.merchant.dto.MerchantDTO;
import com.cencat.merchant.dto.MerchantQueryDTO;
import com.cencat.merchant.dto.MerchantBatchUpdateDTO;
import com.cencat.merchant.dto.MerchantStatisticsDTO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 商户管理服务实现类
 * 提供商户的增删改查、统计分析、信用评估、业务分析等功能的具体实现
 * 
 * @author cencat
 * @version 1.0
 * @since 2025-01-20
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class MerchantServiceImpl implements MerchantService {

    @Autowired
    private MerchantMapper merchantMapper;

    @Override
    public Page<MerchantVO> getMerchantList(Page<Merchant> page, MerchantQueryDTO queryDTO) {
        Page<Merchant> merchantPage = merchantMapper.selectMerchantPage(page, queryDTO);
        Page<MerchantVO> voPage = new Page<>(merchantPage.getCurrent(), merchantPage.getSize(), merchantPage.getTotal());
        
        List<MerchantVO> voList = merchantPage.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
        voPage.setRecords(voList);
        
        return voPage;
    }

    @Override
    public MerchantVO getMerchantById(Long id) {
        Merchant merchant = merchantMapper.selectById(id);
        return merchant != null ? convertToVO(merchant) : null;
    }

    @Override
    public Boolean createMerchant(MerchantDTO merchantDTO) {
        // 检查商户编号是否已存在
        if (existsByMerchantNo(merchantDTO.getMerchantNo(), null)) {
            throw new RuntimeException("商户编号已存在: " + merchantDTO.getMerchantNo());
        }
        
        // 检查商户名称是否已存在
        if (existsByMerchantName(merchantDTO.getMerchantName(), null)) {
            throw new RuntimeException("商户名称已存在: " + merchantDTO.getMerchantName());
        }
        
        Merchant merchant = convertToEntity(merchantDTO);
        merchant.setCreateTime(LocalDateTime.now());
        merchant.setUpdateTime(LocalDateTime.now());
        
        return merchantMapper.insert(merchant) > 0;
    }

    @Override
    public Boolean updateMerchant(Long id, MerchantDTO merchantDTO) {
        Merchant existingMerchant = merchantMapper.selectById(id);
        if (existingMerchant == null) {
            throw new RuntimeException("商户不存在: " + id);
        }
        
        // 检查商户编号是否已存在（排除当前记录）
        if (existsByMerchantNo(merchantDTO.getMerchantNo(), id)) {
            throw new RuntimeException("商户编号已存在: " + merchantDTO.getMerchantNo());
        }
        
        // 检查商户名称是否已存在（排除当前记录）
        if (existsByMerchantName(merchantDTO.getMerchantName(), id)) {
            throw new RuntimeException("商户名称已存在: " + merchantDTO.getMerchantName());
        }
        
        Merchant merchant = convertToEntity(merchantDTO);
        merchant.setId(id);
        merchant.setUpdateTime(LocalDateTime.now());
        
        return merchantMapper.updateById(merchant) > 0;
    }

    @Override
    public Boolean deleteMerchant(Long id) {
        Merchant merchant = merchantMapper.selectById(id);
        if (merchant == null) {
            throw new RuntimeException("商户不存在: " + id);
        }
        
        return merchantMapper.deleteById(id) > 0;
    }

    @Override
    public Boolean batchDeleteMerchants(List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return false;
        }
        
        return merchantMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public Boolean batchUpdateMerchantStatus(MerchantBatchUpdateDTO batchUpdateDTO) {
        if (CollectionUtils.isEmpty(batchUpdateDTO.getIds())) {
            return false;
        }
        
        return merchantMapper.batchUpdateMerchantStatus(
                batchUpdateDTO.getIds(), 
                batchUpdateDTO.getStatus()
        ) > 0;
    }

    @Override
    public Boolean batchUpdateCreditLevel(List<Long> ids, String creditLevel) {
        if (CollectionUtils.isEmpty(ids)) {
            return false;
        }
        
        return merchantMapper.batchUpdateCreditLevel(ids, creditLevel) > 0;
    }

    @Override
    public Boolean batchUpdateServiceFeeRate(List<Long> ids, BigDecimal serviceFeeRate) {
        if (CollectionUtils.isEmpty(ids)) {
            return false;
        }
        
        return merchantMapper.batchUpdateServiceFeeRate(ids, serviceFeeRate) > 0;
    }

    @Override
    public Boolean batchUpdateSettlementCycle(List<Long> ids, Integer settlementCycle) {
        if (CollectionUtils.isEmpty(ids)) {
            return false;
        }
        
        return merchantMapper.batchUpdateSettlementCycle(ids, settlementCycle) > 0;
    }

    @Override
    public Map<String, Object> getMerchantStatistics(MerchantStatisticsDTO statisticsDTO) {
        Map<String, Object> result = new HashMap<>();
        
        // 总商户数
        Long totalCount = merchantMapper.selectCount(null);
        result.put("totalCount", totalCount);
        
        // 活跃商户数
        Long activeCount = merchantMapper.countByStatus("ACTIVE");
        result.put("activeCount", activeCount);
        
        // 待审核商户数
        Long pendingCount = merchantMapper.countByStatus("PENDING");
        result.put("pendingCount", pendingCount);
        
        // 已停用商户数
        Long inactiveCount = merchantMapper.countByStatus("INACTIVE");
        result.put("inactiveCount", inactiveCount);
        
        // 已冻结商户数
        Long frozenCount = merchantMapper.countByStatus("FROZEN");
        result.put("frozenCount", frozenCount);
        
        // 按信用等级统计
        Map<String, Long> creditLevelStats = new HashMap<>();
        creditLevelStats.put("AAA", merchantMapper.countByCreditLevel("AAA"));
        creditLevelStats.put("AA", merchantMapper.countByCreditLevel("AA"));
        creditLevelStats.put("A", merchantMapper.countByCreditLevel("A"));
        creditLevelStats.put("B", merchantMapper.countByCreditLevel("B"));
        creditLevelStats.put("C", merchantMapper.countByCreditLevel("C"));
        result.put("creditLevelStats", creditLevelStats);
        
        return result;
    }

    @Override
    public List<MerchantVO> getActiveMerchants(Integer limit) {
        List<Merchant> merchants = merchantMapper.selectActiveMerchants(limit);
        return merchants.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public List<MerchantVO> getPendingMerchants(Integer limit) {
        List<Merchant> merchants = merchantMapper.selectPendingMerchants(limit);
        return merchants.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public List<MerchantVO> getInactiveMerchants(Integer limit) {
        List<Merchant> merchants = merchantMapper.selectInactiveMerchants(limit);
        return merchants.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public List<MerchantVO> getHighCreditMerchants(String minCreditLevel, Integer limit) {
        List<Merchant> merchants = merchantMapper.selectHighCreditMerchants(minCreditLevel, limit);
        return merchants.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public List<MerchantVO> getTopPerformingMerchants(Integer limit) {
        List<Merchant> merchants = merchantMapper.selectTopPerformingMerchants(limit);
        return merchants.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public List<MerchantVO> getMerchantsByRegion(String region, String status, Integer limit) {
        List<Merchant> merchants = merchantMapper.selectMerchantsByRegion(region, status, limit);
        return merchants.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public List<MerchantVO> getMerchantsByIndustry(String industry, String status, Integer limit) {
        List<Merchant> merchants = merchantMapper.selectMerchantsByIndustry(industry, status, limit);
        return merchants.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public List<MerchantVO> getMerchantsByTimeRange(LocalDateTime startTime, LocalDateTime endTime, Integer limit) {
        List<Merchant> merchants = merchantMapper.selectMerchantsByTimeRange(startTime, endTime, limit);
        return merchants.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public List<MerchantVO> getMerchantsByServiceFeeRange(BigDecimal minFee, BigDecimal maxFee, Integer limit) {
        List<Merchant> merchants = merchantMapper.selectMerchantsByServiceFeeRange(minFee, maxFee, limit);
        return merchants.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public List<MerchantVO> getMerchantsBySettlementCycle(Integer settlementCycle, String status, Integer limit) {
        List<Merchant> merchants = merchantMapper.selectMerchantsBySettlementCycle(settlementCycle, status, limit);
        return merchants.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public List<MerchantVO> intelligentRecommendMerchants(String requirements, Integer limit) {
        // 智能推荐商户逻辑
        List<Merchant> merchants = merchantMapper.selectIntelligentRecommendMerchants(requirements, limit);
        return merchants.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public Boolean existsById(Long id) {
        return merchantMapper.selectById(id) != null;
    }

    @Override
    public Boolean existsByMerchantNo(String merchantNo, Long excludeId) {
        return merchantMapper.existsByMerchantNo(merchantNo, excludeId) > 0;
    }

    @Override
    public Boolean existsByMerchantName(String merchantName, Long excludeId) {
        return merchantMapper.existsByMerchantName(merchantName, excludeId) > 0;
    }

    @Override
    public Boolean activateMerchant(Long merchantId, String activationReason) {
        Merchant merchant = merchantMapper.selectById(merchantId);
        if (merchant == null) {
            throw new RuntimeException("商户不存在: " + merchantId);
        }
        
        merchant.setStatus("ACTIVE");
        merchant.setUpdateTime(LocalDateTime.now());
        
        return merchantMapper.updateById(merchant) > 0;
    }

    @Override
    public Boolean deactivateMerchant(Long merchantId, String deactivationReason) {
        Merchant merchant = merchantMapper.selectById(merchantId);
        if (merchant == null) {
            throw new RuntimeException("商户不存在: " + merchantId);
        }
        
        merchant.setStatus("INACTIVE");
        merchant.setUpdateTime(LocalDateTime.now());
        
        return merchantMapper.updateById(merchant) > 0;
    }

    @Override
    public Boolean freezeMerchant(Long merchantId, String freezeReason) {
        Merchant merchant = merchantMapper.selectById(merchantId);
        if (merchant == null) {
            throw new RuntimeException("商户不存在: " + merchantId);
        }
        
        merchant.setStatus("FROZEN");
        merchant.setUpdateTime(LocalDateTime.now());
        
        return merchantMapper.updateById(merchant) > 0;
    }

    @Override
    public Boolean unfreezeMerchant(Long merchantId, String unfreezeReason) {
        Merchant merchant = merchantMapper.selectById(merchantId);
        if (merchant == null) {
            throw new RuntimeException("商户不存在: " + merchantId);
        }
        
        merchant.setStatus("ACTIVE");
        merchant.setUpdateTime(LocalDateTime.now());
        
        return merchantMapper.updateById(merchant) > 0;
    }

    @Override
    public Boolean approveMerchant(Long merchantId, String approvalNotes) {
        Merchant merchant = merchantMapper.selectById(merchantId);
        if (merchant == null) {
            throw new RuntimeException("商户不存在: " + merchantId);
        }
        
        merchant.setStatus("ACTIVE");
        merchant.setUpdateTime(LocalDateTime.now());
        
        return merchantMapper.updateById(merchant) > 0;
    }

    @Override
    public Boolean rejectMerchant(Long merchantId, String rejectionReason) {
        Merchant merchant = merchantMapper.selectById(merchantId);
        if (merchant == null) {
            throw new RuntimeException("商户不存在: " + merchantId);
        }
        
        merchant.setStatus("REJECTED");
        merchant.setUpdateTime(LocalDateTime.now());
        
        return merchantMapper.updateById(merchant) > 0;
    }

    @Override
    public Boolean updateMerchantCreditLevel(Long merchantId, String creditLevel, String reason) {
        return merchantMapper.updateMerchantCreditLevel(merchantId, creditLevel, reason) > 0;
    }

    @Override
    public Boolean updateServiceFeeRate(Long merchantId, BigDecimal serviceFeeRate, String reason) {
        Merchant merchant = merchantMapper.selectById(merchantId);
        if (merchant == null) {
            throw new RuntimeException("商户不存在: " + merchantId);
        }
        
        merchant.setServiceFeeRate(serviceFeeRate);
        merchant.setUpdateTime(LocalDateTime.now());
        
        return merchantMapper.updateById(merchant) > 0;
    }

    @Override
    public Boolean updateSettlementCycle(Long merchantId, Integer settlementCycle, String reason) {
        Merchant merchant = merchantMapper.selectById(merchantId);
        if (merchant == null) {
            throw new RuntimeException("商户不存在: " + merchantId);
        }
        
        merchant.setSettlementCycle(settlementCycle);
        merchant.setUpdateTime(LocalDateTime.now());
        
        return merchantMapper.updateById(merchant) > 0;
    }

    @Override
    public Boolean updateMerchantContact(Long merchantId, String contactPerson, String contactPhone, String contactEmail) {
        Merchant merchant = merchantMapper.selectById(merchantId);
        if (merchant == null) {
            throw new RuntimeException("商户不存在: " + merchantId);
        }
        
        merchant.setContactPerson(contactPerson);
        merchant.setContactPhone(contactPhone);
        merchant.setContactEmail(contactEmail);
        merchant.setUpdateTime(LocalDateTime.now());
        
        return merchantMapper.updateById(merchant) > 0;
    }

    @Override
    public Map<String, Object> getMerchantPerformance(Long merchantId, LocalDateTime startTime, LocalDateTime endTime) {
        Map<String, Object> result = new HashMap<>();
        
        // 获取商户绩效数据
        result.put("merchantId", merchantId);
        result.put("period", startTime + " - " + endTime);
        result.put("totalOrders", 0);
        result.put("completedOrders", 0);
        result.put("cancelledOrders", 0);
        result.put("totalRevenue", BigDecimal.ZERO);
        result.put("averageOrderValue", BigDecimal.ZERO);
        result.put("customerSatisfaction", 0.0);
        result.put("onTimeDeliveryRate", 0.0);
        
        return result;
    }

    @Override
    public Map<String, Object> evaluateMerchantCredit(Long merchantId) {
        Map<String, Object> result = new HashMap<>();
        
        // 商户信用评估逻辑
        Merchant merchant = merchantMapper.selectById(merchantId);
        if (merchant == null) {
            return result;
        }
        
        result.put("merchantId", merchantId);
        result.put("currentCreditLevel", merchant.getCreditLevel());
        result.put("creditScore", 0);
        result.put("evaluationDate", LocalDateTime.now());
        result.put("factors", new ArrayList<>());
        result.put("recommendations", new ArrayList<>());
        
        return result;
    }

    @Override
    public BigDecimal calculateMerchantRevenue(Long merchantId, LocalDateTime startTime, LocalDateTime endTime) {
        // 计算商户收入逻辑
        return merchantMapper.calculateMerchantRevenue(merchantId, startTime, endTime);
    }

    @Override
    public Integer calculateMerchantOrderCount(Long merchantId, LocalDateTime startTime, LocalDateTime endTime) {
        // 计算商户订单数逻辑
        return merchantMapper.calculateMerchantOrderCount(merchantId, startTime, endTime);
    }

    @Override
    public Double calculateCustomerSatisfaction(Long merchantId, LocalDateTime startTime, LocalDateTime endTime) {
        // 计算客户满意度逻辑
        return merchantMapper.calculateCustomerSatisfaction(merchantId, startTime, endTime);
    }

    @Override
    public List<MerchantVO> searchMerchants(String keyword, String searchType, Integer limit) {
        List<Merchant> merchants = merchantMapper.searchMerchants(keyword, searchType, limit);
        return merchants.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public List<MerchantVO> exportMerchants(MerchantQueryDTO queryDTO) {
        List<Merchant> merchants = merchantMapper.selectMerchantList(queryDTO);
        return merchants.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public Boolean importMerchants(List<MerchantDTO> merchants) {
        if (CollectionUtils.isEmpty(merchants)) {
            return false;
        }
        
        for (MerchantDTO merchantDTO : merchants) {
            try {
                createMerchant(merchantDTO);
            } catch (Exception e) {
                // 记录导入失败的记录
                System.err.println("导入商户失败: " + merchantDTO.getMerchantNo() + ", 原因: " + e.getMessage());
            }
        }
        
        return true;
    }

    @Override
    public Boolean syncMerchantData(Long merchantId, String syncType) {
        // 商户数据同步逻辑
        Merchant merchant = merchantMapper.selectById(merchantId);
        if (merchant == null) {
            return false;
        }
        
        // 根据同步类型执行不同的同步逻辑
        switch (syncType) {
            case "BASIC_INFO":
                // 同步基本信息
                break;
            case "BUSINESS_INFO":
                // 同步业务信息
                break;
            case "FINANCIAL_INFO":
                // 同步财务信息
                break;
            default:
                // 全量同步
                break;
        }
        
        return true;
    }

    @Override
    public Boolean batchSyncMerchantData(List<Long> merchantIds, String syncType) {
        if (CollectionUtils.isEmpty(merchantIds)) {
            return false;
        }
        
        for (Long merchantId : merchantIds) {
            syncMerchantData(merchantId, syncType);
        }
        
        return true;
    }

    @Override
    public Boolean validateMerchant(Long merchantId, String validationType) {
        // 商户验证逻辑
        Merchant merchant = merchantMapper.selectById(merchantId);
        if (merchant == null) {
            return false;
        }
        
        // 根据验证类型执行不同的验证逻辑
        switch (validationType) {
            case "BUSINESS_LICENSE":
                // 验证营业执照
                break;
            case "BANK_ACCOUNT":
                // 验证银行账户
                break;
            case "CONTACT_INFO":
                // 验证联系信息
                break;
            default:
                // 全面验证
                break;
        }
        
        return true;
    }

    @Override
    public Boolean batchValidateMerchants(List<Long> merchantIds, String validationType) {
        if (CollectionUtils.isEmpty(merchantIds)) {
            return false;
        }
        
        for (Long merchantId : merchantIds) {
            if (!validateMerchant(merchantId, validationType)) {
                return false;
            }
        }
        
        return true;
    }

    @Override
    public Map<String, Object> getMerchantAnalytics(LocalDateTime startTime, LocalDateTime endTime, String analyticsType) {
        Map<String, Object> result = new HashMap<>();
        
        // 获取商户分析数据
        result.put("period", startTime + " - " + endTime);
        result.put("analyticsType", analyticsType);
        result.put("totalMerchants", 0);
        result.put("activeMerchants", 0);
        result.put("newMerchants", 0);
        result.put("averageRevenue", BigDecimal.ZERO);
        result.put("topIndustries", new ArrayList<>());
        result.put("topRegions", new ArrayList<>());
        
        return result;
    }

    @Override
    public List<Map<String, Object>> getMerchantTrends(LocalDateTime startTime, LocalDateTime endTime, String trendType) {
        // 获取商户趋势数据
        return merchantMapper.selectMerchantTrends(startTime, endTime, trendType);
    }

    @Override
    public Boolean settleMerchant(Long merchantId, BigDecimal settlementAmount, String settlementNotes) {
        // 商户结算逻辑
        Merchant merchant = merchantMapper.selectById(merchantId);
        if (merchant == null) {
            return false;
        }
        
        // 执行结算逻辑
        // 更新商户余额、记录结算记录等
        
        return true;
    }

    @Override
    public Boolean batchSettleMerchants(List<Long> merchantIds, String settlementType) {
        if (CollectionUtils.isEmpty(merchantIds)) {
            return false;
        }
        
        for (Long merchantId : merchantIds) {
            // 根据结算类型计算结算金额
            BigDecimal settlementAmount = BigDecimal.ZERO;
            settleMerchant(merchantId, settlementAmount, "批量结算");
        }
        
        return true;
    }

    @Override
    public Boolean auditMerchant(Long merchantId, String auditResult, String auditNotes) {
        // 商户审核逻辑
        Merchant merchant = merchantMapper.selectById(merchantId);
        if (merchant == null) {
            return false;
        }
        
        // 根据审核结果更新商户状态
        switch (auditResult) {
            case "APPROVED":
                merchant.setStatus("ACTIVE");
                break;
            case "REJECTED":
                merchant.setStatus("REJECTED");
                break;
            case "PENDING":
                merchant.setStatus("PENDING");
                break;
        }
        
        merchant.setUpdateTime(LocalDateTime.now());
        return merchantMapper.updateById(merchant) > 0;
    }

    @Override
    public Boolean batchAuditMerchants(List<Long> merchantIds, String auditResult, String auditNotes) {
        if (CollectionUtils.isEmpty(merchantIds)) {
            return false;
        }
        
        for (Long merchantId : merchantIds) {
            auditMerchant(merchantId, auditResult, auditNotes);
        }
        
        return true;
    }

    /**
     * 将Merchant实体转换为MerchantVO
     */
    private MerchantVO convertToVO(Merchant merchant) {
        if (merchant == null) {
            return null;
        }
        
        MerchantVO vo = new MerchantVO();
        BeanUtils.copyProperties(merchant, vo);
        return vo;
    }

    /**
     * 将MerchantDTO转换为Merchant实体
     */
    private Merchant convertToEntity(MerchantDTO dto) {
        if (dto == null) {
            return null;
        }
        
        Merchant entity = new Merchant();
        BeanUtils.copyProperties(dto, entity);
        return entity;
    }
}